#include "dbusvaluedelegate.hpp"
#include "dbusargvitem.hpp"
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qdebug.h>
//#include "propertydialog.h"
DBusValueDelegate::DBusValueDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
    bytes_show_mode= BytesShowMode_HEX;
}

QWidget *DBusValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    DBusArgvItem *item = static_cast<DBusArgvItem*>(index.internalPointer());

    if(item!=Q_NULLPTR)
    {
        if(item->getValueType()<QMetaType::User && index.column () == 2)
        {
            if(item->getValueType() == QMetaType::Bool)
            {
                return NULL;
            }else
            {
                QLineEdit *editer = new QLineEdit(parent) ;
                setValidator(item,editer);
                return editer;
            }
        }else if(item->getValueType()<QMetaType::User && index.column () == 3)
        {
            if(item->getValueType() == QMetaType::Char
                     || item->getValueType() == QMetaType::UChar
                     || item->getValueType() == QMetaType::Short
                     || item->getValueType() == QMetaType::UShort
                     || item->getValueType() == QMetaType::Int
                     || item->getValueType() == QMetaType::UInt
                     || item->getValueType() == QMetaType::LongLong
                     || item->getValueType() == QMetaType::ULongLong
                     || item->getValueType() == QMetaType::QByteArray
                     )
            {
                QComboBox *editer = new QComboBox(parent) ;
                editer->addItem ("Default",ShowModelDefault);
                editer->addItem ("Hex",ShowModelHex);
                return editer;
            }
        }
    }
    return NULL;

}
void DBusValueDelegate::setValidator(const DBusArgvItem *item,QLineEdit *editer) const
{
    int type = item->getValueType();
    if(type == QMetaType::Char || type == QMetaType::UChar)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,2})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
            val->setRange (0,255);
            editer->setValidator (val);
        }
    }else if(type == QMetaType::Short)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,4})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
//            val->setRange (-32768,32767);
            editer->setValidator (val);
        }

    }else if(type == QMetaType::UShort)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,4})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
//            val->setRange (0,65535);
            editer->setValidator (val);
        }
    }else if(type == QMetaType::Int)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,8})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
//            val->setRange (-2147483648,2147483648);
            editer->setValidator (val);
        }
    }else if(type == QMetaType::UInt)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,8})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
//            val->setRange (0,4294967295);
            editer->setValidator (val);
        }
    }else if(type == QMetaType::LongLong)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,16})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
            editer->setValidator (val);
        }
    }else if(type == QMetaType::ULongLong)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,16})");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }else
        {
            QIntValidator *val = new QIntValidator(editer);
//            val->setBottom (0);
            editer->setValidator (val);
        }
    }else if(type == QMetaType::QByteArray)
    {
        if(item->m_showModel == ShowModelHex){
            QRegExp regExp("^([0-9A-Fa-f]{1,2})(\\s([0-9A-Fa-f]{1,2}))*");
            editer->setValidator(new QRegExpValidator(regExp, editer));
        }
    }
}

void DBusValueDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    DBusArgvItem *item = static_cast<DBusArgvItem*>(index.internalPointer());
    if(item!=Q_NULLPTR)
    {
        if(item->getValueType()<QMetaType::User  && index.column () == 2)
        {
            if(item->getValueType() == QMetaType::Bool)
            {

            }else
            {
                QString text = index.model()->data(index, Qt::DisplayRole).toString();
                QLineEdit* lineEdit = static_cast<QLineEdit*>(editor);
                lineEdit->setText(text);
            }
        }else if(item->getValueType()<QMetaType::User && index.column () == 3)
        {
                QComboBox* lineEdit = static_cast<QComboBox*>(editor);
                if(item->m_showModel == ShowModelDefault)
                {
                    lineEdit->setCurrentIndex (0);
                }else
                {
                    lineEdit->setCurrentIndex (1);
                }

        }
    }
}

void DBusValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
     DBusArgvItem *item = static_cast<DBusArgvItem*>(index.internalPointer());
    QVariant t = index.model()->data(index, Qt::UserRole);
    if(item!=Q_NULLPTR)
    {
        if(item->getValueType()<QMetaType::User  && index.column () == 2)
        {
            if(item->getValueType() == QMetaType::Bool)
            {

            }else
            {
                QLineEdit* lineEdit = static_cast<QLineEdit*>(editor);
                QString text = lineEdit->text();

                if(item->getValueType() == QMetaType::Char
                         || item->getValueType() == QMetaType::Short
                         || item->getValueType() == QMetaType::Int
                         || item->getValueType() == QMetaType::LongLong
                         )
                {
                    bool ok = 0;
                    if(item->m_showModel == ShowModelHex)
                    {

                        qlonglong ddd = text.toULongLong (&ok,16);
                        model->setData(index, ddd, Qt::EditRole);
                    }else
                    {
                        qlonglong ddd = text.toLongLong (&ok);
                        model->setData(index, ddd, Qt::EditRole);
                    }
                }else if(item->getValueType() == QMetaType::UChar
                         || item->getValueType() == QMetaType::UShort
                         || item->getValueType() == QMetaType::UInt
                         || item->getValueType() == QMetaType::ULongLong
                         )
                {
                    bool ok = 0;
                    if(item->m_showModel == ShowModelHex)
                    {
                        qulonglong ddd = text.toULongLong(&ok,16);
                        model->setData(index, ddd, Qt::EditRole);
                    }else
                    {
                        qulonglong ddd = text.toULongLong (&ok);
                        model->setData(index, ddd, Qt::EditRole);
                    }
                }else if(item->getValueType() == QMetaType::QByteArray)
                {
                    bool ok = 0;
                    if(item->m_showModel == ShowModelHex)
                    {
                        QByteArray ddd = QByteArray::fromHex (text.toLatin1 ());
                        model->setData(index, ddd, Qt::EditRole);
                    }else
                    {
                        text = text.replace ("\\r","\r");
                        text = text.replace ("\\n","\n");
                        model->setData(index,text, Qt::EditRole);
                    }
                }else if(item->getValueType() == QMetaType::QString)
                {
                    text = text.replace ("\\r","\r");
                    text = text.replace ("\\n","\n");
                    model->setData(index, text, Qt::EditRole);
                }else if(item->getValueType() == QMetaType::Double)
                {
                    model->setData(index, text, Qt::EditRole);
                }


            }
        }else if(item->getValueType()<QMetaType::User && index.column () == 3)
        {
//            if(item->getValueType() == QMetaType::QString)
            {
                QVariant v;
                QComboBox* lineEdit = static_cast<QComboBox*>(editor);
                int sel = lineEdit->currentData ().toInt ();
                if(sel == 0)
                {
                    v = (int)ShowModelDefault;
                }else
                {
                     v = (int)ShowModelHex;
                }
                model->setData(index, v, Qt::EditRole);
            }
        }
    }
}

int DBusValueDelegate::getBytes_show_mode() const
{
    return bytes_show_mode;
}

void DBusValueDelegate::setBytes_show_mode(int value)
{
    bytes_show_mode = value;
}

//void DBusValueDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
//{
//    DBusArgvItem *item = static_cast<DBusArgvItem*>(index.internalPointer());
//    if(item!=Q_NULLPTR)
//    {
//        if(item->getValueType() == QMetaType::Bool)
//        {
//            if(index.column () ==2)
//            {
//                option->index = index;
//                option->checkStates = QStyle::State_On;
//                option->state = QStyle::State_Enabled;
//                option->features |= QStyleOptionViewItem::HasCheckIndicator;

//            }
//        }

//    }
//    QStyledItemDelegate::initStyleOption (option,index);
//}
